/**
 * NeuroSky数据解析器
 * 
 * 这个类用于解析从NeuroSky设备通过蓝牙接收到的数据包
 * 基于NeuroSky ThinkGear协议，解析各种脑电波数据
 * 
 * 主要功能：
 * - 解析数据包头和校验和
 * - 提取注意力、冥想、原始数据等指标
 * - 提供回调机制通知数据更新
 */
package com.example.test_bluetooth

class NeuroSkyDataParser {
    
    // 数据变量
    var attention: Int = 0
        private set
    var meditation: Int = 0
        private set
    var rawValue: Int = 0
        private set
    var delta: Int = 0
        private set
    var theta: Int = 0
        private set
    var lowAlpha: Int = 0
        private set
    var highAlpha: Int = 0
        private set
    var lowBeta: Int = 0
        private set
    var highBeta: Int = 0
        private set
    var lowGamma: Int = 0
        private set
    var midGamma: Int = 0
        private set
    var poorSignal: Int = 0
        private set
    var blinkStrength: Int = 0
        private set
    
    // 回调接口
    interface DataCallback {
        fun onAttentionUpdate(value: Int)
        fun onMeditationUpdate(value: Int)
        fun onRawValueUpdate(value: Int)
        fun onPoorSignalUpdate(value: Int)
        fun onBlinkUpdate(value: Int)
        fun onEEGUpdate(delta: Int, theta: Int, lowAlpha: Int, highAlpha: Int, 
                       lowBeta: Int, highBeta: Int, lowGamma: Int, midGamma: Int)
    }
    
    private var callback: DataCallback? = null
    
    fun setCallback(callback: DataCallback) {
        this.callback = callback
    }
    
    /**
     * 解析数据包
     * @param data 接收到的字节数组
     */
    fun parseData(data: ByteArray) {
        var i = 0
        while (i < data.size - 1) {
            // 查找包头 0xAA 0xAA
            if (data[i].toInt() and 0xFF == 0xAA && 
                data[i + 1].toInt() and 0xFF == 0xAA) {
                
                i += 2
                if (i >= data.size) break
                
                val payloadLength = data[i].toInt() and 0xFF
                i++
                
                if (i + payloadLength >= data.size) break
                
                // 提取payload
                val payload = ByteArray(payloadLength)
                System.arraycopy(data, i, payload, 0, payloadLength)
                i += payloadLength
                
                if (i >= data.size) break
                
                // 验证校验和
                val checksum = data[i].toInt() and 0xFF
                var calculatedChecksum = 0
                for (b in payload) {
                    calculatedChecksum += b.toInt() and 0xFF
                }
                calculatedChecksum = (calculatedChecksum.inv() and 0xFF)
                
                if (checksum == calculatedChecksum) {
                    parsePayload(payload)
                }
                i++
            } else {
                i++
            }
        }
    }
    
    /**
     * 解析payload数据
     */
    private fun parsePayload(payload: ByteArray) {
        var i = 0
        while (i < payload.size) {
            val code = payload[i].toInt() and 0xFF
            
            when (code) {
                0x02 -> { // Poor Signal
                    i++
                    if (i < payload.size) {
                        poorSignal = payload[i].toInt() and 0xFF
                        callback?.onPoorSignalUpdate(poorSignal)
                    }
                }
                0x04 -> { // Attention
                    i++
                    if (i < payload.size) {
                        attention = payload[i].toInt() and 0xFF
                        callback?.onAttentionUpdate(attention)
                    }
                }
                0x05 -> { // Meditation
                    i++
                    if (i < payload.size) {
                        meditation = payload[i].toInt() and 0xFF
                        callback?.onMeditationUpdate(meditation)
                    }
                }
                0x16 -> { // Blink Strength
                    i++
                    if (i < payload.size) {
                        blinkStrength = payload[i].toInt() and 0xFF
                        callback?.onBlinkUpdate(blinkStrength)
                    }
                }
                0x80 -> { // Raw Value
                    i++ // skip length
                    i++
                    if (i + 1 < payload.size) {
                        val val0 = payload[i].toInt() and 0xFF
                        val val1 = payload[i + 1].toInt() and 0xFF
                        rawValue = val0 * 256 + val1
                        if (rawValue > 32768) {
                            rawValue -= 65536
                        }
                        callback?.onRawValueUpdate(rawValue)
                        i++
                    }
                }
                0x83 -> { // ASIC EEG Power
                    i++ // skip length
                    if (i + 23 < payload.size) {
                        // Delta (3 bytes)
                        i++
                        val delta0 = payload[i].toInt() and 0xFF
                        val delta1 = payload[i + 1].toInt() and 0xFF
                        val delta2 = payload[i + 2].toInt() and 0xFF
                        delta = delta0 * 65536 + delta1 * 256 + delta2
                        i += 2
                        
                        // Theta (3 bytes)
                        i++
                        val theta0 = payload[i].toInt() and 0xFF
                        val theta1 = payload[i + 1].toInt() and 0xFF
                        val theta2 = payload[i + 2].toInt() and 0xFF
                        theta = theta0 * 65536 + theta1 * 256 + theta2
                        i += 2
                        
                        // Low Alpha (3 bytes)
                        i++
                        val lowAlpha0 = payload[i].toInt() and 0xFF
                        val lowAlpha1 = payload[i + 1].toInt() and 0xFF
                        val lowAlpha2 = payload[i + 2].toInt() and 0xFF
                        lowAlpha = lowAlpha0 * 65536 + lowAlpha1 * 256 + lowAlpha2
                        i += 2
                        
                        // High Alpha (3 bytes)
                        i++
                        val highAlpha0 = payload[i].toInt() and 0xFF
                        val highAlpha1 = payload[i + 1].toInt() and 0xFF
                        val highAlpha2 = payload[i + 2].toInt() and 0xFF
                        highAlpha = highAlpha0 * 65536 + highAlpha1 * 256 + highAlpha2
                        i += 2
                        
                        // Low Beta (3 bytes)
                        i++
                        val lowBeta0 = payload[i].toInt() and 0xFF
                        val lowBeta1 = payload[i + 1].toInt() and 0xFF
                        val lowBeta2 = payload[i + 2].toInt() and 0xFF
                        lowBeta = lowBeta0 * 65536 + lowBeta1 * 256 + lowBeta2
                        i += 2
                        
                        // High Beta (3 bytes)
                        i++
                        val highBeta0 = payload[i].toInt() and 0xFF
                        val highBeta1 = payload[i + 1].toInt() and 0xFF
                        val highBeta2 = payload[i + 2].toInt() and 0xFF
                        highBeta = highBeta0 * 65536 + highBeta1 * 256 + highBeta2
                        i += 2
                        
                        // Low Gamma (3 bytes)
                        i++
                        val lowGamma0 = payload[i].toInt() and 0xFF
                        val lowGamma1 = payload[i + 1].toInt() and 0xFF
                        val lowGamma2 = payload[i + 2].toInt() and 0xFF
                        lowGamma = lowGamma0 * 65536 + lowGamma1 * 256 + lowGamma2
                        i += 2
                        
                        // Mid Gamma (3 bytes)
                        i++
                        val midGamma0 = payload[i].toInt() and 0xFF
                        val midGamma1 = payload[i + 1].toInt() and 0xFF
                        val midGamma2 = payload[i + 2].toInt() and 0xFF
                        midGamma = midGamma0 * 65536 + midGamma1 * 256 + midGamma2
                        i += 2
                        
                        callback?.onEEGUpdate(delta, theta, lowAlpha, highAlpha, 
                                            lowBeta, highBeta, lowGamma, midGamma)
                    }
                }
            }
            i++
        }
    }
}